#ifndef GAME_HPP
#define GAME_HPP

#include <QObject>
#include <QDataStream>

#include "client.hpp"
#include "lobby.hpp"
#include "mainwindow.hpp"
#include "goban.hpp"

class Client;
class Lobby;
class MainWindow;

class Game : public QObject
{
    Q_OBJECT

public:
    enum ClientType
    {
        BLACK,
        WHITE,
        OBSERVER,
        NONE
    };

private:
    Lobby * _lobby;
    MainWindow * _mainWindow;
    Goban * _goban;

    quint8 _id;
    static quint8 s_id;

    quint8 _gobanSize;
    qreal _komi;

    bool _isStarted;
    bool _isEstablishingScore;
    bool _isFinished;

    bool _blackToPlay;
    bool _lastTurnSkipped;

    bool _blackValidated;
    bool _whiteValidated;

    Client * _black;
    Client * _white;
    QList<Client *> _observers;

    qreal _blackScore;
    qreal _whiteScore;

    bool isIn(Client * client) const;
    bool isPlayingIn(Client * client) const;
    bool isObserving(Client * client) const;
    ClientType clientState(Client * client) const;
    ClientType clientState(const QString & name) const;
    Client * whoIsIt(const QString & name) const;

    void kill();

public:
    Game(Lobby * lobby, Client * black, quint8 gobanSize, qreal komi, MainWindow * parent = 0);

    quint8 id() const;

    void writeForList(QDataStream & out) const;
    void writeForState(QDataStream & out) const;

    void reactPlayMove(Client * player, quint8 x, quint8 y);
    void skipTurn(Client * client);
    void reactDeadGroup(quint8 x, quint8 y);
    void reactAliveGroup(quint8 x, quint8 y);

    void reactToPlay(Client * client);
    void reactValidateGroups(Client * client);

signals:
    void ragequit(quint8 playerID); // {0;1} stands for BLACK;WHITE

public slots:
    void addPlayer(Client * client);
    void addObserver(Client * client);

    void clientLeft(const QString & name);
    bool destroy(const Client * client); // Returns true if the game has been destroyed successfully (not started yet, or not the black)

    void someoneSaid(const QString & name, const QString & message);
};

#endif // GAME_HPP
